//this map use qt QHash and  inhert from GMap
//andycai_sc implement 2011-05-26

#ifndef GQTHASHMAP_H
#define GQTHASHMAP_H

#include "GTpl/IGMap.h"
#include <QString>
#include <string>
using std::string;
Q_CORE_EXPORT uint qHash(const QString &key);
inline uint qHash(const string &key)
{
    QString qStr(key.c_str());
    return qHash(qStr);
}
#include <QHash>

template<typename Key, typename Value>
class GHashMap : public GMap<Key, Value>
{
public:
    GHashMap() {}
    virtual ~GHashMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    void erase(typename GMap<Key, Value>::IterPtr position);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

private:
    QHash<Key, Value> m_qHash;
    class HIterator : public GMap<Key, Value>::Iterator
    {
    public:
        HIterator(const typename QHash<Key, Value>::iterator& it) { m_iter = it; }
        HIterator(const HIterator& hit) { m_iter = hit.m_iter; }
        virtual ~HIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;

        typename QHash<Key, Value>::iterator getOrigIter() const
        {
            return m_iter;
        }

    private:
        typename QHash<Key, Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMap<Key, Value>::insert(const Key& key, const Value& value)
{
    typename QHash<Key, Value>::iterator it = m_qHash.insert(key, value);
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
int GHashMap<Key, Value>::erase(const Key& key)
{
    int count = 0;
    typename QHash<Key, Value>::iterator it = m_qHash.find(key);
    while (it != m_qHash.end() && it.key() == key)
    {
        it = m_qHash.erase(it);
        ++it;
        ++count;
    }
    return count;
}

template<typename Key, typename Value>
void GHashMap<Key, Value>::erase(typename GMap<Key, Value>::IterPtr position)
{
    HIterator* hIt = dynamic_cast<HIterator*>(position.get());
    assert(hIt != 0);
    m_qHash.erase(hIt->getOrigIter());
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMap<Key, Value>::find(const Key& key)
{
    typename QHash<Key, Value>::iterator it = m_qHash.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMap<Key, Value>::begin()
{
    typename QHash<Key, Value>::iterator it = m_qHash.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMap<Key, Value>::end()
{
    typename QHash<Key, Value>::iterator it = m_qHash.end();
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GHashMap<Key, Value>::HIterator::clone()
{
    return new HIterator(*this);
}

template<typename Key, typename Value>
const Key& GHashMap<Key, Value>::HIterator::getKey()
{
    return m_iter.key();
}

template<typename Key, typename Value>
Value& GHashMap<Key, Value>::HIterator::getValue()
{
    return m_iter.value();
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMap<Key, Value>::HIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMap<Key, Value>::HIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMap<Key, Value>::HIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMap<Key, Value>::HIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GHashMap<Key, Value>::HIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const HIterator& hIt = dynamic_cast<const HIterator&>(it);
    return m_iter == hIt.m_iter;
}

template<typename Key, typename Value>
bool GHashMap<Key, Value>::HIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const HIterator& hIt = dynamic_cast<const HIterator&>(it);
    return m_iter != hIt.m_iter;
}

//----------------------------GHashMultiMap implement------------------------------------

template<typename Key, typename Value>
class GHashMultiMap : public GMap<Key, Value>
{
public:
    GHashMultiMap() {}
    virtual ~GHashMultiMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    void erase(typename GMap<Key, Value>::IterPtr position);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

    typename GMap<Key, Value>::Range equal_range(const Key& key);

private:
    QMultiHash<Key, Value> m_qHash;
    class HIterator : public GMap<Key, Value>::Iterator
    {
    public:
        HIterator(const typename QMultiHash<Key, Value>::iterator& it) { m_iter = it; }
        HIterator(const HIterator& hit) { m_iter = hit.m_iter; }
        virtual ~HIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;

        typename QMultiHash<Key, Value>::iterator getOrigIter() const
        {
            return m_iter;
        }

    private:
        typename QMultiHash<Key, Value>::iterator m_iter;
    };
    QList<Value> m_values;
    class MIterator : public GMap<Key, Value>::Iterator
    {
    public:
        MIterator(const Key& key, const typename QList<Value>::iterator& it)
        {
            m_key = key;
            m_iter = it;
        }
        MIterator(const MIterator& it)
        {
            m_key = it.m_key;
            m_iter = it.m_iter;
        }
        virtual ~MIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;
    private:
        Key m_key;
        typename QList<Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMultiMap<Key, Value>::insert(const Key& key, const Value& value)
{
    typename QMultiHash<Key, Value>::iterator it = m_qHash.insert(key, value);
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
int GHashMultiMap<Key, Value>::erase(const Key& key)
{
    int count = 0;
    typename QHash<Key, Value>::iterator it = m_qHash.find(key);
    while (it != m_qHash.end() && it.key() == key)
    {
        it = m_qHash.erase(it);
        ++it;
        ++count;
    }
    return count;
}

template<typename Key, typename Value>
void GHashMultiMap<Key, Value>::erase(typename GMap<Key, Value>::IterPtr position)
{
    HIterator* hIt = dynamic_cast<HIterator*>(position.get());
    assert(hIt != 0);
    m_qHash.erase(hIt->getOrigIter());
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMultiMap<Key, Value>::find(const Key& key)
{
    typename QMultiHash<Key, Value>::iterator it = m_qHash.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMultiMap<Key, Value>::begin()
{
    typename QMultiHash<Key, Value>::iterator it = m_qHash.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GHashMultiMap<Key, Value>::end()
{
    typename QMultiHash<Key, Value>::iterator it = m_qHash.end();
    typename GMap<Key, Value>::IterPtr itPtr(new HIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Range GHashMultiMap<Key, Value>::equal_range(const Key& key)
{
    m_values = m_qHash.values(key);
    typename GMap<Key, Value>::IterPtr itPtrF(new MIterator(key, m_values.begin()));
    typename GMap<Key, Value>::IterPtr itPtrL(new MIterator(key, m_values.end()));
    return typename GMap<Key, Value>::Range(itPtrF, itPtrL);
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GHashMultiMap<Key, Value>::HIterator::clone()
{
    return new HIterator(*this);
}

template<typename Key, typename Value>
const Key& GHashMultiMap<Key, Value>::HIterator::getKey()
{
    return m_iter.key();
}

template<typename Key, typename Value>
Value& GHashMultiMap<Key, Value>::HIterator::getValue()
{
    return m_iter.value();
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::HIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::HIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::HIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::HIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GHashMultiMap<Key, Value>::HIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const HIterator& hIt = dynamic_cast<const HIterator&>(it);
    return m_iter == hIt.m_iter;
}

template<typename Key, typename Value>
bool GHashMultiMap<Key, Value>::HIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const HIterator& hIt = dynamic_cast<const HIterator&>(it);
    return m_iter != hIt.m_iter;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GHashMultiMap<Key, Value>::MIterator::clone()
{
    return new MIterator(*this);
}

template<typename Key, typename Value>
const Key& GHashMultiMap<Key, Value>::MIterator::getKey()
{
    return m_key;
}

template<typename Key, typename Value>
Value& GHashMultiMap<Key, Value>::MIterator::getValue()
{
    return *m_iter;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::MIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::MIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::MIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GHashMultiMap<Key, Value>::MIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GHashMultiMap<Key, Value>::MIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const MIterator& mIt = dynamic_cast<const MIterator&>(it);
    return (m_key == mIt.m_key && m_iter == mIt.m_iter);
}

template<typename Key, typename Value>
bool GHashMultiMap<Key, Value>::MIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const MIterator& mIt = dynamic_cast<const MIterator&>(it);
    return (m_key != mIt.m_key || m_iter != mIt.m_iter);
}

#endif // GQTHASHMAP_H
